package com.wgke.bluetooth.tools;

import android.util.Log;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class BtMsg {

    public static final int UINT8 = 0x01;   // 无符号，1字节
    public static final int INT8 = 0x11;     // 有符号，1字节
    public static final int UINT16 = 0x02;   // 无符号，2字节
    public static final int INT16 = 0x12;    // 有符号，2字节
    public static final int UINT32 = 0x04;   // 无符号，4字节
    public static final int INT32 = 0x14;    // 有符号，4字节

    public static boolean isLittleEndian = true; // 所有数据小端传输
    public static int sendSeq = 1;

    private ByteBuffer buffer;
    private int pos = 0;

    // 构造ByteBuffer
    public BtMsg(byte[] buf) {
        buffer = ByteBuffer.wrap(buf);
        buffer.order(isLittleEndian ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN);
    }


    // 获取帧号 10-255之间循环
    public int getIncSeq() {
        if (++sendSeq > 255) {
            sendSeq = 1;
        }
        return sendSeq;
    }

    // 设置指令头部信息
    public void setHeader(int cmd) {
        pos = 0;
        setUnit(UINT16, 0x6868);//根据项目不同是要不停改变的
        setUnit(UINT8, getIncSeq());
        setUnit(UINT8, cmd);
        setUnit(UINT16, buffer.array().length - 6);
        pos = 6;
    }

    public void setUnit(int type, long value) {
        switch (type) {
            case UINT8:
            case INT8:
                buffer.put(pos, (byte) value);
                break;
            case UINT16:
            case INT16:
                buffer.putShort(pos, (short) value);
                break;
            case UINT32:
            case INT32:
                buffer.putInt(pos, (int) value);
                break;
        }
        pos += type & 0x0F;
    }

    // 获取单元数据
    public long getUnit(int type) {
        if (pos + (type & 0x0F) > buffer.capacity()) {
            return 0;
        }
        long ret = 0;
        switch (type) {
            case UINT8:
                ret = buffer.get(pos) & 0xFFL; // 无符号处理
                break;
            case INT8:
                ret = buffer.get(pos);
                break;
            case UINT16:
                ret = buffer.getShort(pos) & 0xFFFFL; // 无符号处理
                break;
            case INT16:
                ret = buffer.getShort(pos);
                break;
            case UINT32:
                ret = buffer.getInt(pos) & 0xFFFFFFFFL; // 无符号处理
                break;
            case INT32:
                ret = buffer.getInt(pos);
                break;
        }
        pos += type & 0x0F;
        return ret;
    }


    // 写入字符串类型unit
    public void setStringUnit(String str, int size) {
        if (pos + size > buffer.capacity()) {
            throw new IndexOutOfBoundsException("setStringField out of range");
        }

        byte[] bytes = str.getBytes();
        int length = Math.min(bytes.length, size);
        for (int i = 0; i < length; i++) {
            buffer.put(pos + i, bytes[i]);
        }

        if (length < size) {
            buffer.put(pos + length, (byte) 0);
        }
        pos += size;
    }

    // 获取字符串类型unit
    public String getStringUnit(int size) {
        if (pos + size > buffer.capacity()) {
            throw new IndexOutOfBoundsException("getStringField out of range");
        }

        byte[] bytes = new byte[size];
        for (int i = 0; i < size; i++) {
            bytes[i] = buffer.get(pos + i);
        }
        pos += size;

        // 找到第一个0截断
        int len = 0;
        while (len < bytes.length && bytes[len] != 0) {
            len++;
        }
        return new String(bytes, 0, len);
    }

    // 设置位置
    public void setPos(int newPos) {
        if (newPos < 0 || newPos >= buffer.capacity()) {
            throw new IndexOutOfBoundsException("newPos out of range");
        }
        pos = newPos;
    }

    // 获取位置
    public int getPos() {
        return pos;
    }

    // 获取命令
    public int getCmd() {
        return (int) getUnitFromBuffer(3, UINT8);
    }

    // 获取长度
    public int getLength() {
        return (int) getUnitFromBuffer(4, UINT16);
    }

    // 内部方法：从指定位置获取数据
    private long getUnitFromBuffer(int position, int type) {
        int oldPos = pos;
        pos = position;
        long value = getUnit(type);
        pos = oldPos;
        return value;
    }

    // 跳转到消息净荷头部
    public void moveToNetMsg() {
        setPos(6);
    }

    // 填充CRC (暂留空)
    public void fillCrc() {
        // todo: to fill crc here
    }

    // 检查CRC (暂留空)
    public boolean checkCrc() {
        // todo: to check crc here
        return true;
    }

    // 16进制打印消息内容
    public void printHex() {
        StringBuilder sb = new StringBuilder("printHex--- ");
        for (int i = 0; i < buffer.capacity(); i++) {
            sb.append(String.format("%02X", buffer.get(i)));
            if (i < buffer.capacity() - 1) {
                sb.append(",");
            }
        }
        System.out.println(sb.toString());
    }

    // 获取底层字节数组
    public byte[] getBytes() {
        return buffer.array();
    }


    public static String byteArrayToHexString(byte[] byteArray) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : byteArray) {
            hexString.append(String.format("%02X ", b));
        }
        return hexString.toString();
    }
    /**
     * 长字符串转byte[]
     * 例如：68 68 10 94 0F 00 01 02 03
     * */
    public static byte[] hexStringToByteArray(String hexString) {
        // 移除所有空格
        String cleanedHex = hexString.replaceAll("\\s", "");

        // 检查长度是否为偶数（每个字节需要2个16进制字符）
        if (cleanedHex.length() % 2 != 0) {
            return null;
        }
        try {
            byte[] byteArray = new byte[cleanedHex.length() / 2];
            for (int i = 0; i < byteArray.length; i++) {
                int index = i * 2;
                String hexByte = cleanedHex.substring(index, index + 2);
                byteArray[i] = (byte) Integer.parseInt(hexByte, 16);
            }
            return byteArray;
        } catch (Exception e) {
            Log.e("BtMsg", "hexStringToByteArray: e->"+e);
        }
        return null;
    }
}
